package com.hunan.chinamobile.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.hunan.chinamobile.constant.SysConstant;
import com.hunan.chinamobile.dao.*;
import com.hunan.chinamobile.model.*;
import com.hunan.chinamobile.push.MessagePush;
import com.hunan.chinamobile.service.OneNetService;
import com.hunan.chinamobile.util.SMSUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class OneNetServiceImpl implements OneNetService {

    @Resource
    private SysSmsMapper sysSmsMapper;
    @Resource
    private BaseStationMapper baseStationMapper;
    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private DeviceDataMapper deviceDataMapper;
    @Resource
    private DeviceLineDataMapper deviceLineDataMapper;
    @Resource
    private DeviceRealtimeDataMapper deviceRealtimeDataMapper;
    @Resource
    private ExceptionsMapper exceptionsMapper;
    @Resource
    private HUserMapper hUserMapper;

    @Transactional
    @Override
    public void handler(JSONObject jsonObject) {
        int type = jsonObject.getIntValue("type");
        if(type == 1){
            saveRealtimeData(jsonObject);
            saveDeviceData(jsonObject);
            handlerExceptionData(jsonObject);
        }else if(type == 2){
            saveDeviceLineData(jsonObject);
        }
    }

    private void handlerExceptionData(JSONObject jsonObject){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int type = jsonObject.getIntValue("type");
        long createAt = jsonObject.getLong("at");
        int devId = jsonObject.getIntValue("dev_id");
        String imei = jsonObject.getString("imei");
        String dsId = jsonObject.getString("ds_id");
        String value = jsonObject.getString("value");
        String deviceId = value.substring(0,8);
        String voltageSignalVal = value.substring(24,26);
        String fiberOpticVal = value.substring(26,28);
        String voltageVal = value.substring(28,32);
        String rssi = "99";
        if(value.length() == 34) {
            rssi = value.substring(32, 34);
        }

        if(deviceId.equals("00000000")){
            System.out.println("=>  设备编号为空："+jsonObject.toJSONString());
            return;
        }

        Exceptions voltageE = exceptionsMapper.findByCondition(deviceId,1,0);
//        Exceptions fiberOpticE = exceptionsMapper.findByCondition(deviceId,2,0);

        Device deviceObj = deviceMapper.findByDeviceId(deviceId);
        BaseStation bsObj = baseStationMapper.selectByPrimaryKey(deviceObj.getBsId());

        boolean vs = true;
        boolean fs = true;

        List<SysSms> sss = sysSmsMapper.selectAll();

        if(voltageSignalVal.equals("00") || voltageSignalVal.equals("02") || voltageSignalVal.equals("04")){
            vs = false;
            deviceMapper.updateStateByOneNetId(2,devId);
            // 电压信号为00时表示设备离线
            deviceMapper.updateOnlineByOneNetId(0,devId);
            if(voltageE == null){
                Exceptions ve = new Exceptions();
                ve.setState(false);
                ve.setHappenAt(new Date(createAt));
                ve.setId(UUID.randomUUID().toString());
                ve.setDeviceId(deviceId);
                ve.setType(1);
                ve.setCreatedAt(new Date());
                ve.setUpdatedAt(new Date());
                exceptionsMapper.insert(ve);

                MessagePush.pushErrorData("设备位置:"+deviceObj.getAddress()+","+deviceObj.getNbName()+",电压信号发生故障,发生时间:"+sdf.format(getHappenDate(value)),
                        getUserIds(bsObj.getCityId()),"stationError",bsObj.getId());

                if(sss != null && sss.get(0).getSwitchState()) {
                    SMSUtil.sendError(bsObj.getLinkphone(),deviceObj.getNbName(),deviceObj.getDeviceId(), deviceObj.getAddress(), getHappenDateStr(value),
                            SysConstant.getRssi(Integer.parseInt(rssi)), Integer.parseInt(voltageVal)+"V", vs ? "正常" : "异常", fs ? "正常" : "异常");
                }
            }
        }else if(voltageSignalVal.equals("01")){
            // 电压信号为01时表示设备在线
            deviceMapper.updateOnlineByOneNetId(1,devId);
            updateException(voltageE,createAt);
            if(voltageE != null){
                MessagePush.pushErrorData("设备位置:"+deviceObj.getAddress()+","+deviceObj.getNbName()+",电压信号故障恢复,恢复时间:"+sdf.format(new Date(createAt)),
                        getUserIds(bsObj.getCityId()),"stationRecover",bsObj.getId());
                SMSUtil.sendRecover(bsObj.getLinkphone(),deviceObj.getAddress(),deviceObj.getNbName(),"电压信号",new Date(createAt));
            }
        }

//        if(fiberOpticVal.equals("00")){
//            fs = false;
//            deviceMapper.updateStateByOneNetId(2,devId);
//            if(fiberOpticE == null){
//                Exceptions ve = new Exceptions();
//                ve.setState(false);
//                ve.setHappenAt(new Date(createAt));
//                ve.setId(UUID.randomUUID().toString());
//                ve.setDeviceId(deviceId);
//                ve.setType(2);
//                ve.setCreatedAt(new Date());
//                ve.setUpdatedAt(new Date());
//                exceptionsMapper.insert(ve);
//
//                MessagePush.pushErrorData("设备位置:"+deviceObj.getAddress()+","+deviceObj.getNbName()+",光纤信号发生故障,发生时间:"+sdf.format(getHappenDate(value)),
//                        getUserIds(bsObj.getCityId()),"stationError",bsObj.getId());
//
//                if(sss != null && sss.get(0).getSwitchState()) {
//                    SMSUtil.sendError(bsObj.getLinkphone(),deviceObj.getNbName(),deviceObj.getDeviceId(), deviceObj.getAddress(), getHappenDateStr(value),
//                            SysConstant.getRssi(Integer.parseInt(rssi)), Integer.parseInt(voltageVal)+"V", vs ? "正常" : "异常", fs ? "正常" : "异常");
//                }
//            }
//        }else if(fiberOpticVal.equals("01")){
//            updateException(fiberOpticE,createAt);
//            if(fiberOpticE != null){
//                MessagePush.pushErrorData("设备位置:"+deviceObj.getAddress()+","+deviceObj.getNbName()+",光纤信号故障恢复,恢复时间:"+sdf.format(new Date(createAt)),
//                        getUserIds(bsObj.getCityId()),"stationRecover",bsObj.getId());
//                SMSUtil.sendRecover(bsObj.getLinkphone(),deviceObj.getAddress(),deviceObj.getNbName(),"光纤信号",new Date(createAt));
//            }
//        }

        if(voltageSignalVal.equals("01")){ // && fiberOpticVal.equals("01")
            deviceMapper.updateStateByOneNetId(1,devId);
        }
    }

    private void updateException(Exceptions fiberOpticE,long happenTime) {
        if(fiberOpticE != null){
            fiberOpticE.setState(true);
            fiberOpticE.setRecoverAt(new Date(happenTime));
            fiberOpticE.setUpdatedAt(new Date());
            exceptionsMapper.updateByPrimaryKeySelective(fiberOpticE);
        }
    }

    private void saveDeviceLineData(JSONObject jsonObject){
        int type = jsonObject.getIntValue("type");
        long createAt = jsonObject.getLong("at");
        int devId = jsonObject.getIntValue("dev_id");
        String imei = jsonObject.getString("imei");
        int loginType = jsonObject.getIntValue("login_type");
        int status = jsonObject.getIntValue("status");
        DeviceLineData dld = new DeviceLineData();
        dld.setId(UUID.randomUUID().toString());
        dld.setCreatedAt(new Date(createAt));
        dld.setImei(imei);
        dld.setLoginType(loginType);
        dld.setType(type);
        dld.setOneNetId(devId);
        dld.setStatus(status);
        deviceLineDataMapper.insert(dld);
        deviceMapper.updateOnlineByOneNetId(status,devId);
    }

    private void saveDeviceData(JSONObject jsonObject){
        int type = jsonObject.getIntValue("type");
        long createAt = jsonObject.getLong("at");
        int devId = jsonObject.getIntValue("dev_id");
        String imei = jsonObject.getString("imei");
        String dsId = jsonObject.getString("ds_id");
        String value = jsonObject.getString("value");
        String deviceId = value.substring(0,8);
        String voltageSignalVal = value.substring(24,26);
        String fiberOpticVal = value.substring(26,28);
        String voltageVal = value.substring(28,32);
        if(voltageVal.startsWith("8")){
            voltageVal = "-"+voltageVal.substring(1);
        }
        String rssi = "99";
        if(value.length() == 34) {
            rssi = value.substring(32, 34);
        }

        DeviceData vsDD = getDD(imei,devId,dsId,value,1,Double.parseDouble(voltageSignalVal),createAt);
        DeviceData foDD = getDD(imei,devId,dsId,value,2,Double.parseDouble(fiberOpticVal),createAt);
        DeviceData vDD = getDD(imei,devId,dsId,value,3,Double.parseDouble(voltageVal),createAt);
        DeviceData rssiDD = getDD(imei,devId,dsId,value,4,Double.parseDouble(rssi),createAt);

        List<DeviceData> dds = new ArrayList<>();
        dds.add(vsDD);
        dds.add(foDD);
        dds.add(vDD);
        dds.add(rssiDD);

        deviceDataMapper.insertList(dds);
    }

    private void saveRealtimeData(JSONObject jsonObject){
        int type = jsonObject.getIntValue("type");
        long createAt = jsonObject.getLong("at");
        int devId = jsonObject.getIntValue("dev_id");
        String imei = jsonObject.getString("imei");
        String dsId = jsonObject.getString("ds_id");
        String value = jsonObject.getString("value");
        DeviceRealtimeData drd = new DeviceRealtimeData();
        drd.setId(UUID.randomUUID().toString());
        drd.setCreatedAt(new Date(createAt));
        drd.setImei(imei);
        drd.setOneNetId(devId);
        drd.setResouceId(dsId);
        drd.setType(type);
        drd.setValue(value);
        deviceRealtimeDataMapper.insert(drd);
    }


    private DeviceData getDD(String imei,int devId,String dsId,String souce,int type,double val,long createdAt){
        String deviceId = souce.substring(0,8);
        String deviceType = souce.substring(8,10);
        DeviceData dd = new DeviceData();
        dd.setCreatedAt(new Date(createdAt));
        dd.setDeviceId(deviceId);
        dd.setImei(imei);
        dd.setOneNetId(devId);
        dd.setResouceId(dsId);
        dd.setType(type);
        dd.setValue(val);
        return dd;
    }

    private Date getHappenDate(String source){
        String date = source.substring(10,24);
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR,Integer.parseInt(date.substring(0,4)));
        c.set(Calendar.MONTH,Integer.parseInt(date.substring(4,6))-1);
        c.set(Calendar.DAY_OF_MONTH,Integer.parseInt(date.substring(6,8)));
        c.set(Calendar.HOUR_OF_DAY,Integer.parseInt(date.substring(8,10)));
        c.set(Calendar.MINUTE,Integer.parseInt(date.substring(10,12)));
        c.set(Calendar.SECOND, Integer.parseInt(date.substring(12,14)));
        return c.getTime();
    }

    private String getHappenDateStr(String source){
        String date = source.substring(10,24);
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR,Integer.parseInt(date.substring(0,4)));
        c.set(Calendar.MONTH,Integer.parseInt(date.substring(4,6))-1);
        c.set(Calendar.DAY_OF_MONTH,Integer.parseInt(date.substring(6,8)));
        c.set(Calendar.HOUR_OF_DAY,Integer.parseInt(date.substring(8,10)));
        c.set(Calendar.MINUTE,Integer.parseInt(date.substring(10,12)));
        c.set(Calendar.SECOND, Integer.parseInt(date.substring(12,14)));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(c.getTime());
    }

    private List<String> getUserIds(String cityId){
        List<User> userList = hUserMapper.selectAll();
        List<String> uidList = new ArrayList<>();
        if(userList != null && userList.size() > 0){
            for(User user : userList){
                if(StringUtils.isEmpty(user.getCityId()) || cityId.equals(user.getCityId()))
                    uidList.add(user.getId().replace("-",""));
            }
        }
        return uidList;
    }
}
